<template>
  <a-modal
    title="图表"
    :width="1000"
    v-model:visible="visible"
    :ok-loading="confirmLoading"
    :mask-closable="false"
    unmount-on-close
    ok-text="确认"
    @ok="handleOk"
    @cancel="close"
    :body-style="{ 'max-height': '700px', overflow: 'auto' }"
  >
    <a-spin :spinning="confirmLoading">
      <variable-selection
        :var-options="varOptions"
        v-if="visible && varVisible"
      ></variable-selection>
      <a-form
        layout="vertical"
        ref="form"
        :model="form"
        :rules="rules"
        @submit="handleSubmit"
        @submit.native.prevent
      >
        <a-row :gutter="24">
          <a-col :md="8" :sm="24">
            <a-form-item label="图表选择" field="chartType">
              <a-select
                placeholder="请选择图表"
                v-model="form.chartType"
                allow-clear
              >
                <a-option
                  v-for="item in chartOptions"
                  :key="item.value"
                  :value="item.value"
                  >{{ item.label }}
                </a-option>
                <!-- <a-option>折线图</a-option> -->
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="数据源选择" field="dataId">
              <a-select
                v-model="form.dataId"
                :filter-option="false"
                @change="queryDataSourceDetails($event)"
                @search="queryDatasourceList"
                :show-search="true"
                placeholder="请选择数据源"
                allow-clear
              >
                <a-option
                  v-for="item in dataSourceList"
                  :key="item.dataId"
                  :value="item.dataId"
                  :title="item.dataName"
                >
                  {{ item.dataName }}
                </a-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :md="8" :sm="24">
            <a-form-item label="窗口大小" field="chartSize">
              <a-input-number
                v-model="form.chartSize"
                :min="1"
                :max="10000"
              ></a-input-number>
            </a-form-item>
          </a-col>
        </a-row>
        <a-divider>显示内容</a-divider>
        <div style="margin-bottom: 10px">
          <a-button @click="addGrids"
            ><icon-plus style="margin-right: 6px" />增加{{
              ["Gather"].includes(form.chartType) ? "显示板块" : "分组"
            }}</a-button
          >
        </div>
        <!--  显示内容   -->
        <a-row
          v-for="(grid, index) in form.gridsList"
          :key="index"
          :gutter="16"
          justify="space-between"
        >
          <a-col :md="2" :sm="2" v-if="['Gantt'].includes(form.chartType)">
            <a-form-item label="隐藏列">
              <a-checkbox
                v-model="grid.hide"
                style="margin-left: 15px; margin-top: 5px"
              ></a-checkbox>
            </a-form-item>
          </a-col>
          <a-col :md="5" :sm="24">
            <a-form-item :label="gridNameLabel(index)">
              <a-input
                v-model="grid.gridName"
                placeholder="请输入名称"
              ></a-input>
            </a-form-item>
          </a-col>
          <a-col :md="5" :sm="24">
            <a-form-item label="数值">
              <a-input
                v-model="grid.gridValue"
                placeholder="请输入变量"
              ></a-input>
            </a-form-item>
          </a-col>
          <a-col :md="5" :sm="24" v-if="form.chartType === 'Gather'">
            <a-form-item label="查询报表">
              <a-select
                placeholder="请选择"
                v-model="grid.gridEventId"
                @change="onChangeButtonItem($event, grid)"
                :show-search="true"
              >
                <a-option
                  v-for="item in buttonList"
                  :key="item.eventId"
                  :value="item.eventId"
                  :label="item.formName + '_' + item.buttonName"
                >
                  {{ item.formName + "_" + item.buttonName }}
                </a-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col
            :md="6"
            :sm="24"
            v-if="['Gather', 'Gantt'].includes(form.chartType)"
          >
            <a-form-item label="单位">
              <a-input
                v-model="grid.gridUnit"
                placeholder="请输入单位"
                style="width: 90%"
              ></a-input>
              <icon-minus-circle
                style="margin-left: 5px; color: #ff4d4f"
                @click="removeGrids(index)"
              />
            </a-form-item>
          </a-col>
          <a-col :md="6" :sm="24" v-else>
            <a-form-item label="单位">
              <span>使用Y轴单位</span>
              <icon-minus-circle
                style="margin-left: 5px; color: #ff4d4f"
                @click="removeGrids(index)"
              />
            </a-form-item>
          </a-col>
        </a-row>
        <a-divider>坐标轴</a-divider>
        <a-row>
          <span v-if="!['Pie', 'Gather'].includes(form.chartType)">
            <a-col :md="8" :sm="24">
              <a-form-item :label="xLabel" field="xName">
                <a-input
                  placeholder="请输入名称"
                  v-model="form.xName"
                  style="width: 220px"
                ></a-input>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item :label="xFieldLabel" field="xField">
                <!-- <a-select placeholder="请选择X轴字段" style="width: 220px" v-model="form.xField" allowClear>
              <a-option v-for="item in dataShowFieldOptions" :key="item.columnAs" :value="item.columnAs">
                {{ item.columnAs }}
              </a-option>
            </a-select> -->
                <a-input
                  v-model="form.xField"
                  style="width: 220px"
                  placeholder="请输入变量"
                ></a-input>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="单位">
                <a-input
                  placeholder="请输入单位"
                  v-model="form.xUnit"
                  style="width: 220px"
                ></a-input>
              </a-form-item>
            </a-col>
          </span>

          <template v-if="!['Gather'].includes(form.chartType)">
            <a-col :md="8" :sm="24">
              <a-form-item :label="yLabel" field="yName">
                <a-input
                  placeholder="请输入名称"
                  v-model="form.yName"
                  style="width: 220px"
                ></a-input>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item :label="yFieldLabel" field="yField">
                <!-- <a-select placeholder="请选择Y轴字段" style="width: 220px" v-model="form.yField" allowClear>
              <a-option v-for="item in dataShowFieldOptions" :key="item.columnAs" :value="item.columnAs">
                {{ item.columnAs }}
              </a-option>
            </a-select> -->
                <a-input
                  v-model="form.yField"
                  style="width: 220px"
                  placeholder="请输入变量"
                ></a-input>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="单位">
                <a-input
                  placeholder="请输入单位"
                  v-model="form.yUnit"
                  style="width: 220px"
                ></a-input>
              </a-form-item>
            </a-col>
          </template>
          <!--        <a-form-item label="分组字段" style="margin-left: 5px" v-if="!['Gather'].includes(form.chartType)">-->
          <!--          <a-select placeholder="请选择字段" style="width: 220px" v-model="form.seriesField" allowClear>-->
          <!--            <a-option v-for="item in dataShowFieldOptions" :key="item.columnAs" :value="item.columnAs">-->
          <!--              {{ item.columnAs }}-->
          <!--            </a-option>-->
          <!--          </a-select>-->
          <!--        </a-form-item>-->
        </a-row>
        <a-form-item>
          <a-button
            type="primary"
            html-type="submit"
            v-if="form.chartType === 'Gather'"
            :disabled="!form.chartType || !form.dataId"
          >
            测试图表
          </a-button>
          <a-button
            type="primary"
            html-type="submit"
            v-else-if="form.chartType === 'Pie'"
            :disabled="!form.chartType || !form.dataId || !form.yField"
          >
            测试图表
          </a-button>
          <a-button
            type="primary"
            html-type="submit"
            v-else
            :disabled="
              !form.chartType || !form.dataId || !form.xField || !form.yField
            "
          >
            测试图表
          </a-button>
        </a-form-item>
      </a-form>
      <a-empty description="生成图表失败" v-if="status === false" />
      <div id="container"></div>
      <interview-count-grid
        :grids-data="gridsData"
        v-if="showChartType === 'Gather'"
      ></interview-count-grid>
      <GanttChart
        ref="GanttChart"
        :tasks="gridsData"
        :config="form"
        v-if="showChartType === 'Gantt'"
      />
    </a-spin>
  </a-modal>
</template>
<script>
import { Bar, Column, Line, Pie } from "@antv/g2plot";
import { clearNullValues } from "@/utils/util";
import InterviewCountGrid from "@/views/formDesign/modal/InterviewCountGrid.vue";
import _ from "lodash";
import VariableSelection from "@/components/Custom/VariableSelection.vue";
import { getChartDataDeal } from "@/mixins/methodsMixins";
import GanttChart from "@/views/formDesign/components/GanttChart.vue";

export default {
  components: {
    VariableSelection,
    InterviewCountGrid,
    GanttChart,
  },
  inject: ["dataObj"],
  computed: {
    xLabel() {
      const { chartType } = this.form;
      if (chartType === "Gantt") {
        return "开始时间";
      } else {
        return "X轴名称";
      }
    },
    xFieldLabel() {
      const { chartType } = this.form;
      if (chartType === "Gantt") {
        return "值字段";
      } else {
        return "X轴字段";
      }
    },
    yLabel() {
      const { chartType } = this.form;
      if (chartType === "Pie") {
        return "名称";
      } else if (chartType === "Gantt") {
        return "进度";
      } else {
        return "Y轴名称";
      }
    },
    yFieldLabel() {
      const { chartType } = this.form;
      if (chartType === "Pie" || chartType === "Gantt") {
        return "值字段";
      } else {
        return "Y轴字段";
      }
    },
    form() {
      if (this.current) {
        return this.dataObj.buttonData[this.current]?.chartConfig || {};
      } else {
        return {};
      }
    },
    varOptions() {
      return this.dataShowFieldOptions.map((item) => ({
        value: item.columnAs,
        label: item.columnAs,
      }));
    },
  },
  data() {
    return {
      buttonList: [], // 按钮列表
      exeRawData: {},
      showChartType: undefined, // 汇总图表是否展示
      gridsData: undefined, // 汇总图表数据
      visible: false,
      varVisible: false,
      confirmLoading: false,
      status: undefined,
      dataShowFieldOptions: [], // 数据源展示字段
      chartOptions: [
        { label: "折线图", value: "Line" },
        { label: "柱状图", value: "Column" },
        { label: "条形图", value: "Bar" },
        { label: "饼图", value: "Pie" },
        { label: "汇总", value: "Gather" },
        { label: "甘特图", value: "Gantt" },
      ],
      dataSourceList: [], // 数据源选项
      rules: {
        dataId: [{ required: true, message: "必填" }],
        chartType: [{ required: true, message: "必填" }],
        xName: [{ required: true, message: "必填" }],
        xField: [{ required: true, message: "必填" }],
        yField: [{ required: true, message: "必填" }],
        yName: [{ required: true, message: "必填" }],
      },
      current: null, // 选择buttonData下标
      chartElement: undefined, // 存储图表实例
    };
  },
  watch: {
    visible(newVal) {
      setTimeout(() => {
        this.varVisible = newVal; // 给变量按钮一个缓冲显示的时间
      }, 400);
    },
  },
  methods: {
    onChangeButtonItem(eventId, item) {
      const buttonData = this.buttonList.find((e) => e.eventId === eventId);
      console.log(buttonData, item, "dasd");
      this.$set(item, "gridEventId", eventId);
      this.$set(item, "gridReportConfig", buttonData);
    },
    async queryButtonList() {
      try {
        const { data } = await this.$http.get("/screen/queryByFormButton");
        this.buttonList = data;
      } catch (e) {
        console.error(e);
      }
    },
    gridNameLabel(index) {
      const { chartType } = this.form;
      if (["Gather"].includes(chartType)) {
        return "板块名称";
      } else if (["Gantt"].includes(chartType)) {
        return "列名";
      } else {
        return "分组名称";
      }
    },
    addGrids() {
      // if (this.form.chartType === 'Gantt' && this.form.gridsList && this.form.gridsList.length > 1) {
      //   this.$message.info('甘特图只能添加两个个分组')
      //   return
      // }
      if (!_.isArray(this.form.gridsList)) {
        this.$set(this.form, "gridsList", []);
      }
      this.form.gridsList.push({
        gridName: "",
        gridValue: "",
        gridUnit: "",
        gridType: "",
      });
    },
    removeGrids(index) {
      this.form.gridsList.splice(index, 1);
    },
    handleSubmit() {
      try {
        this.$refs.form.validate(async (valid) => {
          if (valid) {
            this.confirmLoading = true;
            this.status = null;
            const {
              dataId,
              xName,
              yName,
              yField,
              yUnit,
              chartType,
              gridsList,
            } = this.form;
            if (this.chartElement) {
              // eslint-disable-next-line no-unused-expressions
              this.chartElement?.destroy(); // 先销毁实例
              this.chartElement = undefined;
            }
            const result = await this.$http.post(`/datasource/dataExec`, {
              dataId: dataId,
            });
            const { rows: data } = result.data?.resultPage;
            this.exeRawData = result.data;
            if (chartType === "Gather") {
              // 统计图
              // 汇总取第一条数据
              if (_.isNull(data)) {
                this.gridsData = this.getChartDataDeal({}, this.form);
              } else if (_.isArray(data)) {
                this.gridsData = this.getChartDataDeal(data[0], this.form);
              } else if (_.isObject(data) || data === null) {
                this.gridsData = this.getChartDataDeal(data, this.form);
              }
              console.log(
                this.gridsData,
                "this.gridsDatathis.gridsDatathis.gridsData"
              );
              this.showChartType = "Gather";
              this.status = true;
              return;
            } else if (chartType === "Gantt") {
              this.gridsData = this.getChartDataDeal(
                data,
                this.form,
                this.exeRawData
              );
              console.log(this.gridsData, yName, chartType, "转换完数据");
              this.showChartType = chartType;
              this.status = true;
              return;
            } else {
              this.showChartType = null;
            }
            // 创建一个映射对象，将字符串映射到对应的类
            const chartConstructors = {
              Line: Line, // 如果有其他图表类型，也可以在这里添加，比如 'Bar': Bar
              Bar: Bar,
              Column: Column,
              Pie: Pie,
            };
            let config;
            const _data = this.getChartDataDeal(
              data,
              this.form,
              this.exeRawData
            );
            console.log(_data, yName, chartType, "转换完数据");
            if (["Line", "Bar", "Column"].includes(chartType)) {
              config = {
                data: _data,
                padding: "auto",
                xField: xName,
                yField: yName,
                tooltip: {
                  formatter: (item) => {
                    // item 中包含了数据项的所有信息
                    return {
                      name:
                        gridsList && gridsList.length
                          ? `${item.type}`
                          : `${yName}`, // 如果你想保留原始的name
                      value: `${item[yName]}${yUnit || ""}`, // 在值后面添加 "元"
                    };
                  },
                },
                seriesField: gridsList && gridsList.length ? "type" : undefined,
                isGroup: "true",
                xAxis: {},
              };
              this.chartElement = new chartConstructors[chartType](
                "container",
                config
              );
              this.chartElement.render();
            } else {
              config = {
                data: _data,
                angleField: yName,
                colorField: gridsList && gridsList.length ? "type" : yField,
                radius: 0.9,
                label: {
                  type: "inner",
                  offset: "-30%",
                  content: ({ percent }) => `${(percent * 100).toFixed(0)}%`,
                  style: {
                    fontSize: 14,
                    textAlign: "center",
                  },
                },
                tooltip: {
                  formatter: (item) => {
                    // item 中包含了数据项的所有信息
                    return {
                      name:
                        gridsList && gridsList.length
                          ? `${item.type}`
                          : `${yName}`, // 如果你想保留原始的name
                      value: `${item[yName]}${yUnit || ""}`, // 在值后面添加 "元"
                    };
                  },
                },
                appendPadding: 10,
                interactions: [{ type: "element-active" }],
              };
              this.chartElement = new chartConstructors[chartType](
                "container",
                config
              );
              this.chartElement.render();
            }
            this.status = true;
          }
        });
      } catch (e) {
        console.error("执行错误", e);
        this.status = false;
      } finally {
        this.confirmLoading = false;
      }
    },
    getChartDataDeal,
    handleOk() {
      if (this.status === null || this.status === undefined) {
        this.$message.warn("请先进行测试图表");
      } else if (this.status === false) {
        this.$message.error("测试图表失败，无法保存");
      } else {
        this.dataObj.buttonData[this.current].buttonEventAddDTO.foreignId =
          this.form?.dataId || null;
        this.dataObj.buttonData[this.current].buttonEventAddDTO.param = this
          .form
          ? JSON.stringify(this.form)
          : null;
        this.visible = false;
      }
    },
    async open(current) {
      this.visible = true;
      this.current = current; // 获取下标
      const { dataId } = this.form;
      this.queryButtonList();
      await this.queryDataSourceDetails(dataId, false);
    },
    close() {
      this.visible = false;
    },
    // 选择了数据源，需要查询有哪些展示字段
    async queryDataSourceDetails(dataId, isRest = true) {
      try {
        if (!dataId) return;
        if (isRest) {
          Object.assign(this.dataObj.buttonData[this.current]?.chartConfig, {
            xField: undefined,
            yField: undefined,
            seriesField: undefined,
          });
          if (this.chartElement) {
            this.chartElement.destroy(); // 先销毁实例
          }
        }

        this.status = null;
        const result = await this.$http.get(
          "/datasource/queryDataSourceDetail",
          {
            params: {
              dataId,
            },
          }
        );
        const { data } = result;
        const { dataColumnQueryDTOList, aggregateFunctionInfoReqDTO } = data;
        const { aggregateFunctionInfoAddDTOList } =
          aggregateFunctionInfoReqDTO || {};
        const mergedList = dataColumnQueryDTOList
          .concat(aggregateFunctionInfoAddDTOList || [])
          .concat({ columnAs: "_id" });
        // 需要根据columnKey去重后的对象数组，而不是单纯的columnKey集合，可以进一步处理：
        this.dataShowFieldOptions = mergedList.filter((item, index, self) => {
          return (
            index === self.findIndex((t) => t.columnKey === item.columnKey)
          );
        });
      } catch (e) {
        console.error("失败", e);
      }
    },
    // 查询数据源列表
    async queryDatasourceList(dataName) {
      try {
        // const result = await this.$http.post(
        //   `/datasource/querySourceAllList`,
        //   clearNullValues({
        //     dataTypeList: ["report", "interface"],
        //     dataName: dataName || "",
        //   })
        // );
        // const { data } = result;
        // this.dataSourceList = data;
      } catch (e) {
        console.error("请求失败", e);
      }
    },
  },
  created() {
    this.queryDatasourceList();
  },
};
</script>
<style lang="less" scoped></style>
